<?php


namespace BoojasrMVC\Command;


use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\SymfonyQuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;

class GenerateKeyCommand extends Command
{
    protected function configure(): void
    {
        $this->setName("boo:generate:key")->setDescription("生成密钥对")
            ->setHelp(<<<'EOF'
使用这个 <info>%command.name%</info> 命令，生成新的密钥对:

    <info>php %command.full_name%</info>

EOF
            );
    }



    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);

        /** @var SymfonyQuestionHelper $questionHelper */
        $questionHelper =$this->getHelperSet()->get('question');

        $isSetPassQuestion = new Question($this->getQuestion('是否为这个密钥对设置密码：', "false"),false);
        $isSetPassQuestion->setAutocompleterValues(["true","false","TRUE","FALSE","True","False"]); // 自动补全
        $isSetPass = $questionHelper->ask($input, $output, $isSetPassQuestion);
        $isSetPass = (strtolower($isSetPass) === "true"||$isSetPass === true);
        $passphrase=null;

        if ($isSetPass){
            $password_question = new Question($this->getQuestion('password：', null));
            $password_question->setHidden(true);
            $passphrase = $questionHelper->ask($input, $output, $password_question);
        }

        $r = $this->generateKey($passphrase,true);
        $messge = "私钥：
            {$r["privateKey"]}
            ----------------------------------------------------------------
            公钥：
            {$r["publicKey"]}
        ";
        $io->success($messge);
        return 0;
    }

    /**
     * 密钥配置
     * @var array
     */
    public $config = [
        //指定应该使用多少位来生成私钥 512 1024 2048 4096等
        "private_key_bits" => 1024,
        //选择在创建CSR时应该使用哪些扩展。可选值有 OPENSSL_KEYTYPE_DSA, OPENSSL_KEYTYPE_DH, OPENSSL_KEYTYPE_RSA 或 OPENSSL_KEYTYPE_EC. 默认值是 OPENSSL_KEYTYPE_RSA.
        "private_key_type" => OPENSSL_KEYTYPE_RSA,
    ];

    /**
     * 生成密钥对
     */
    public function generateKey($passphrase=null,$isOriginalReturn=false){
        // 生成公钥私钥资源
        $res = openssl_pkey_new($this->config);
        // 导出私钥 $this->private_key
        openssl_pkey_export($res, $private_key, $passphrase, $this->config);
        // 导出公钥 $pubKey
        $pubKey = openssl_pkey_get_details($res);
        if ($isOriginalReturn){
            return [
                "privateKey"=>$private_key,
                "publicKey"=>$pubKey["key"]
            ];
        }else{
            if ($passphrase){
                return [
                    'privateKey'=>preg_replace("/-----BEGIN ENCRYPTED PRIVATE KEY-----|-----END ENCRYPTED PRIVATE KEY-----|\n/","",$private_key),
                    'publicKey'=>preg_replace("/-----BEGIN PUBLIC KEY-----|-----END PUBLIC KEY-----|\n/",'',$pubKey["key"])
                ];
            }else{
                return [
                    'privateKey'=>preg_replace("/-----BEGIN PRIVATE KEY-----|-----END PRIVATE KEY-----|\n/","",$private_key),
                    'publicKey'=>preg_replace("/-----BEGIN PUBLIC KEY-----|-----END PUBLIC KEY-----|\n/",'',$pubKey["key"])
                ];
            }
        }
    }
    public function getQuestion($question, $default, $sep = ':')
    {
        return $default ? sprintf('<info>%s</info> [<comment>%s</comment>]%s ', $question, $default, $sep) : sprintf('<info>%s</info>%s ', $question, $sep);
    }
}
